<?php

declare(strict_types=1);

namespace app\backend\controller\sys;

use app\common\controller\Basic;
use app\common\service\sys\ClientService;
use app\common\service\sys\InstallService;
use app\common\util\ZipHandle;

/**
 * 应用市场 控制器 -- 特叔。。业务也在此层
 * @author kaige
 * @update  2022-10-19
 * @copyright ©2022 泉州市盛筑信息科技有限公司 版权所有
 */
class Appstore extends Basic
{
    // 初始化
    protected function initialize()
    {
        parent::initialize();
    }

    /**
     * 取云端授权的appid
     */
    public function _appyuninfo()
    {
        $clis = new ClientService();
        $apps = $clis->getInfoByWhere(['type' => 2]);
        if (!$apps) {
            return false;
        }
        return $apps;
    }

    /**
     * 应用市场-列表
     */
    public function index()
    {
        if ($this->request->isGet()) {
            $data = input('param.');
            $result = $this->_getAppStore($data);
            //结合本地安装记录，再输出
            return _jok('', $result);
        }
        return _jerr(1000);
    }

    /**
     * 应用市场 - 类型
     */
    public function apptype()
    {
        if ($this->request->isGet()) {
            $curl    = new \util\Curl();
            $url     = config('kaige.authorization_url') . '/api/appstore/getstoreclass';
            $list =  $curl::curl_request($url, [], [
                'result' => 'json'
            ]);
            return _jok('', $list);
        }
        return _jerr(1000);
    }

    /***
     * 获取应用市场列表
     */
    public function _getAppStore($data)
    {
        $apps = $this->_appyuninfo();
        if (!$apps) {
            return _err('未授权');
        }
        $token = isset($data['yuntoken']) ? $data['yuntoken'] : '';
        $product = config('kaige.product');
        $version = config('kaige.version');
        $url     = config('kaige.authorization_url') . '/api/appstore/getstorelist';
        $domain  = $_SERVER['SERVER_NAME'];
        $curl    = new \util\Curl();
        $params  = [
            'domain'   => $domain,
            'product'  => $product,
            'version'  => $version,
            'page'     => isset($data['page']) ? $data['page'] : 1,
            'limit'    => isset($data['limit']) ? $data['limit'] : 8,
            'keywords' => isset($data['keywords']) ? $data['keywords'] : '',
            'time'     => time(),
        ];
        ksort($params);
        $str = http_build_query($params);
        $sign1 = md5(sha1($str) . $apps['app_salt']);
        $params['signature'] = $sign1;
        $yundata = [
            'method' => 'POST',
            'result' => 'json',
        ];
        if ($token) {
            $yundata['appid'] = $apps['app_id'];
            $yundata['token'] = $token;
        }
        $data = $curl::curl_request($url, $params, $yundata);
        return $data;
    }

    /***
     * 获取我的应用-会员
     */
    public function getmyapplist()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $curl    = new \util\Curl();
            $data = input('param.');
            $params = [
                'ids' => $data['ids']
            ];
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.order/myapplist';
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }
    /**
     * 登录
     */
    public function login()
    {
        if ($this->request->isGet()) {
            return _jok('');
        }
        return _jerr(1000);
    }

    /**
     * 客户端-加入购物车
     */
    public function addcart()
    {
        if ($this->request->isPost()) {
            $data = input('param.');
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $params = [
                'product_id' => $data['product_id']
            ];
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.cart/add';
            $curl    = new \util\Curl();
            $result = $curl::curl_request($url, $params, $uphead);
            return _jok('', $result);
        }
        return _jerr(1000);
    }

    public function cartlist()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $data = input('param.');
            $params = [
                'page' => $data['page'],
                'limit' => $data['limit']
            ];
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.cart/list';
            $curl    = new \util\Curl();
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    public function clearcart()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $data = input('param.');
            $params = [];
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.cart/clearcart';
            $curl    = new \util\Curl();
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    public function delcart()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $data = input('param.');
            $params = [
                'id' => $data['id']
            ];
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.cart/delcart';
            $curl    = new \util\Curl();
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    public function createorder()
    {
        if (!$this->request->isPost() && !$this->request->isGet()) {
            return _jerr(1000);
        }
        $apps = $this->_appyuninfo();
        if (!$apps) {
            return _jerr('未授权');
        }
        $curl    = new \util\Curl();
        if ($this->request->isPost()) {
            $params = input('param.');
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $params['yuntoken'],
            ];
            unset($params['yuntoken']);
            unset($params['signature']);
            $url     = config('kaige.authorization_url') . '/api/shop.order/create';
            $result = $curl::curl_request($url, $params, $uphead);
            return _jok('', $result);
        } else if ($this->request->isGet()) {
            $data = input('param.');
            $params = [];
            $uphead = [
                'method' => 'GET',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $data['yuntoken'],
            ];
            $url     = config('kaige.authorization_url') . '/api/shop.order/create';
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    //我的订单
    public function myorderlist()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $curl    = new \util\Curl();
            $params = input('param.');
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $params['yuntoken'],
            ];
            unset($params['yuntoken']);
            unset($params['signature']);
            $url     = config('kaige.authorization_url') . '/api/shop.order/list';
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    //支付二维码
    public function payqrcode()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $curl    = new \util\Curl();
            $params = input('param.');
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $params['yuntoken'],
            ];
            unset($params['yuntoken']);
            unset($params['signature']);
            $url     = config('kaige.authorization_url') . '/api/shop.order/payqrcode';
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    //支付结果监听
    public function scanpayresult()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $curl    = new \util\Curl();
            $params = input('param.');
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $params['yuntoken'],
            ];
            unset($params['yuntoken']);
            unset($params['signature']);
            $url     = config('kaige.authorization_url') . '/api/shop.order/scanpayresult';
            $result = $curl::curl_request($url, $params, $uphead);
            return  _jok('', $result);
        }
        return _jerr(1000);
    }

    //从外部源下载zip文件
    private function downloadZipFile($url, $filepath)
    {
        $ch = curl_init($url);
        // curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
        $raw_file_data = curl_exec($ch);
        if (curl_errno($ch)) {
            trace('error:' . curl_error($ch));
        }
        curl_close($ch);
        file_put_contents($filepath, $raw_file_data);
        return (filesize($filepath) > 0) ? true : false;
    }


    /**
     * 下载并安装已购买的安装包
     */
    public function downinstall()
    {
        if ($this->request->isPost()) {
            $apps = $this->_appyuninfo();
            if (!$apps) {
                return _jerr('未授权');
            }
            $curl    = new \util\Curl();
            $params = input('param.');
            if (isset($params['appstore_id']) && !empty($params['appstore_id'])) {
            } else {
                return _jerr('安装失败，缺少参数');
            }
            $uphead = [
                'method' => 'POST',
                'result' => 'json',
                'appid' => $apps['app_id'],
                'token' => $params['yuntoken'],
            ];
            unset($params['yuntoken']);
            unset($params['signature']);
            $domain = config('kaige.authorization_url');
            $url = $domain . '/api/shop.download/install';
            $result = $curl::curl_request($url, $params, $uphead);
            if ($result['status']) {
                //获取到安装包，本地处理,此过程没前端什么事。
                $rootpath = root_path();
                $insfilename = 'update' . time() . '.zip';
                $temppath = $rootpath . 'runtime' . DIRECTORY_SEPARATOR . $insfilename;
                $yundata = $result['data'];
                if ($yundata && $yundata['status']) {
                    $insdata = $yundata['data'];
                    $insurl = $domain . $insdata['url'];
                    if (!empty($insurl) && substr($insurl, -4) == '.zip') { //必须是.zip
                        //得到安装包径路，下载后验安装包的hash
                        if ($this->downloadZipFile($insurl, $temppath)) {
                            //比对hash-sha1值
                            $tmphash = hash_file('sha1', $temppath);
                            if ($tmphash == $insdata['hash']) { //相同
                                //解压覆盖安装（在这之前可以加入密码验证再安装）
                                $ziphandle = new ZipHandle();
                                if ($ziphandle->unzip($temppath, $rootpath)) { //在根目录下解压覆盖
                                    //更新数据库--统一路径，每次安装会覆盖
                                    $sqlfile = $rootpath . 'data' . DIRECTORY_SEPARATOR . 'Updatesql.php';
                                    if (file_exists($sqlfile)) { //文件存在，则更新数据库
                                        $px = env('database.prefix', '');
                                        include_once $sqlfile;
                                        if (\Updatesql::install($px)) {
                                            //删除安装包
                                            unlink($temppath);
                                            return _jok('安装成功,数据库更新完成。');
                                        };
                                    }
                                    //删除安装包
                                    unlink($temppath);
                                    //记录安装
                                    (new InstallService())->myinstall([
                                        'appstore_id' => $params['appstore_id'],
                                        'name' => $insdata['hash']['name'],
                                        'version' => $insdata['hash']['version'],
                                        'handle_uid' => $this->user['id'],
                                        'handle_name' => $this->user['real_name']
                                    ]);
                                    return _jok('安装成功,数据库请手动更新');
                                };
                            }
                            return _jerr('安装包错误');
                        };
                        return _jerr('安装包下载失败');
                    }
                }
            }
            return _jerr('安装失败');
        }
        return _jerr(1000);
    }
}
